/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * InjectMethodJDialog.java
 *
 * Created on Jan 4, 2010, 10:40:40 PM
 */
package jaspect;

import jaspect.model.AspectConfiguration;
import jaspect.model.AspectMethod;
import java.util.Map;

/**
 *
 * @author Abin Baby
 */
public class InjectMethodJDialog extends javax.swing.JDialog {

    /** Creates new form InjectMethodJDialog
     * @param parent
     * @param modal
     */
    public InjectMethodJDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        jButton1 = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        tableMethods = new javax.swing.JTable();
        tfMethodName = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        cbBefore = new javax.swing.JCheckBox();
        cbAfter = new javax.swing.JCheckBox();
        cbOnException = new javax.swing.JCheckBox();
        jLabel2 = new javax.swing.JLabel();
        buttonInject = new javax.swing.JButton();
        labelAspectName = new javax.swing.JLabel();
        cbAspectMethod = new javax.swing.JComboBox();
        jLabel3 = new javax.swing.JLabel();
        bInject = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        jButton1.setText("Close");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Methods selection:"));

        tableMethods.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null},
                {null, null, null},
                {null, null, null},
                {null, null, null}
            },
            new String [] {
                "Method Name", "Aspect Method", "Injection Mode"
            }
        ));
        jScrollPane1.setViewportView(tableMethods);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 484, Short.MAX_VALUE)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 484, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 171, Short.MAX_VALUE)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 147, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(24, Short.MAX_VALUE)))
        );

        jLabel1.setText("Method Name");

        cbBefore.setText("Before");

        cbAfter.setText("After");

        cbOnException.setText("On Exception");

        jLabel2.setText("Injection Mode");

        buttonInject.setText("Add");
        buttonInject.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonInjectActionPerformed(evt);
            }
        });

        cbAspectMethod.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbAspectMethodActionPerformed(evt);
            }
        });

        jLabel3.setText("Aspect Method");

        bInject.setText("Inject");
        bInject.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bInjectActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(30, 30, 30)
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(123, 123, 123))
            .addGroup(layout.createSequentialGroup()
                .addGap(118, 118, 118)
                .addComponent(bInject)
                .addGap(96, 96, 96)
                .addComponent(jButton1)
                .addContainerGap(315, Short.MAX_VALUE))
            .addGroup(layout.createSequentialGroup()
                .addGap(20, 20, 20)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jLabel2)
                    .addComponent(jLabel3)
                    .addComponent(jLabel1))
                .addGap(28, 28, 28)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(tfMethodName, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(120, 120, 120)
                        .addComponent(buttonInject))
                    .addComponent(cbAspectMethod, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(cbBefore)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cbAfter)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cbOnException)))
                .addGap(328, 328, 328))
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                    .addContainerGap(510, Short.MAX_VALUE)
                    .addComponent(labelAspectName, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap()))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(tfMethodName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(cbAspectMethod, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(cbBefore)
                    .addComponent(cbAfter)
                    .addComponent(cbOnException))
                .addGap(34, 34, 34)
                .addComponent(buttonInject)
                .addGap(47, 47, 47)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(bInject))
                .addContainerGap(57, Short.MAX_VALUE))
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(365, 365, 365)
                    .addComponent(labelAspectName, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(109, Short.MAX_VALUE)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    /**
     *
     * @param a
     */
    public void setParent(Main a) {
        parent = a;
    }

    /**
     *
     * @param la
     */
    public void listMethods(Map<String, AspectMethod> la) {
        for (AspectMethod am : la.values()) {
            cbAspectMethod.addItem(am);
        }
    }

    /**
     *
     * @param ac
     */
    public void setAspc(AspectConfiguration ac) {
        aspc = ac;
    }
    private void buttonInjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonInjectActionPerformed
        // TODO add your handling code here:
        tableMethods.setValueAt(tfMethodName.getText(), ri, 0);
        tableMethods.setValueAt(cbAspectMethod.getSelectedItem(), ri, 1);

        if (cbBefore.isSelected() == true) {
            tableMethods.setValueAt("before", ri, 2);
        }
        if (cbAfter.isSelected() == true) {
            tableMethods.setValueAt("after", ri, 2);
        }
        if (cbOnException.isSelected() == true) {
            tableMethods.setValueAt("onException", ri, 2);
        }
        ri++;


    }//GEN-LAST:event_buttonInjectActionPerformed

    private void cbAspectMethodActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbAspectMethodActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_cbAspectMethodActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // TODO add your handling code here:
        this.setVisible(false);

    }//GEN-LAST:event_jButton1ActionPerformed

    private void bInjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bInjectActionPerformed

        StringBuilder sb = new StringBuilder();
        sb = toAspectString();
        StringBuilder input = new StringBuilder();
        input.append(parent.getEditorJava().getText());
        int j = input.lastIndexOf("}");

        input.delete(j, j + 1);
        int start = 0;
        int end = 0;
        String aspectName;
        while (true) {
            start = input.indexOf("#", end + 1);
            if (start == -1) {
                break;
            }
            end = input.indexOf("#", start + 1);
            aspectName = input.substring(start + 1, input.indexOf("\n", start));
            if (aspectName.equals(this.aspc.getName())) {
                input.delete(start, end + 1);
                break;
            }
        }
        input.append(sb);
        input.append("\n}");
        parent.getEditorJava().setText(input.toString());
        this.setVisible(false);


    }//GEN-LAST:event_bInjectActionPerformed
    /**
     *
     * @return
     */
    public StringBuilder toAspectString() {
        StringBuilder sb = new StringBuilder();
        try {
            sb.append("#");

                sb.append(aspc.getName());
            for (int i = 0; i < tableMethods.getRowCount(); i++) {
                if (tableMethods.getValueAt(i, 0) == null || tableMethods.getValueAt(i, 1) == null || tableMethods.getValueAt(i, 2) == null) {
                    break;
                }
                
                sb.append("\n");
                sb.append("-" + tableMethods.getValueAt(i, 2) + "(" + tableMethods.getValueAt(i, 0) + ")" + "{\n." + tableMethods.getValueAt(i, 1) + "()\n}");
                sb.append("\n");

            }
        } catch (Exception e) {
            System.out.println("Error in reading the table" + e);

        }

        sb.append("#");
        return sb;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                InjectMethodJDialog dialog = new InjectMethodJDialog(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {

                    @Override
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }
    private Main parent;
    private AspectConfiguration aspc;
    int ri = 0;
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton bInject;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JButton buttonInject;
    private javax.swing.JCheckBox cbAfter;
    private javax.swing.JComboBox cbAspectMethod;
    private javax.swing.JCheckBox cbBefore;
    private javax.swing.JCheckBox cbOnException;
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel labelAspectName;
    private javax.swing.JTable tableMethods;
    private javax.swing.JTextField tfMethodName;
    // End of variables declaration//GEN-END:variables
/**
 * This function accepts the method name 
 * ,injection mode and the corresponding aspect method 
 * and inserts it into a table called methods selection
 * 
 * @param evt
 */
private void buttonInjectActionPerformed1(java.awt.event.ActionEvent evt) {

        tableMethods.setValueAt(tfMethodName.getText(), ri, 0);
        tableMethods.setValueAt(cbAspectMethod.getSelectedItem(), ri, 1);

        if (cbBefore.isSelected() == true) {
            tableMethods.setValueAt("before", ri, 2);
        }
        if (cbAfter.isSelected() == true) {
            tableMethods.setValueAt("after", ri, 2);
        }
        if (cbOnException.isSelected() == true) {
            tableMethods.setValueAt("onException", ri, 2);
        }
        ri++;


    }
/**
 * This code injects the aspect code (placed between the #'s)
 * into the corressponding location depending on the
 * input conditions and modes.
 * @param evt
 */
private void bInjectActionPerformed1(java.awt.event.ActionEvent evt) {

        StringBuilder sb = new StringBuilder();
        sb = toAspectString();
        StringBuilder input = new StringBuilder();
        input.append(parent.getEditorJava().getText());
        int j = input.lastIndexOf("}");

        input.delete(j, j + 1);
        int start = 0;
        int end = 0;
        String aspectName;
        while (true) {
            start = input.indexOf("#", end + 1);
            if (start == -1) {
                break;
            }
            end = input.indexOf("#", start + 1);
            aspectName = input.substring(start + 1, input.indexOf("\n", start));
            if (aspectName.equals(this.aspc.getName())) {
                input.delete(start, end + 1);
                break;
            }
        }
        input.append(sb);
        input.append("\n}");
        parent.getEditorJava().setText(input.toString());
        this.setVisible(false);


    }
    /**
     *This function injects the aspect code.
     * @return
     */
    public StringBuilder toAspectString1() {
        StringBuilder sb = new StringBuilder();
        try {
            sb.append("#");

                sb.append(aspc.getName());
            for (int i = 0; i < tableMethods.getRowCount(); i++) {
                if (tableMethods.getValueAt(i, 0) == null || tableMethods.getValueAt(i, 1) == null || tableMethods.getValueAt(i, 2) == null) {
                    break;
                }

                sb.append("\n");
                sb.append("-" + tableMethods.getValueAt(i, 2) + "(" + tableMethods.getValueAt(i, 0) + ")" + "{\n." + tableMethods.getValueAt(i, 1) + "()\n}");
                sb.append("\n");

            }
        } catch (Exception e) {
            System.out.println("Error in reading the table" + e);

        }

        sb.append("#");
        return sb;
    }
}
